package CutLoad
{
	import CutLoad.components.CTip;
	import CutLoad.cookies.CArray;
	import CutLoad.cookies.Painter;
	import CutLoad.cookies.RandNO;
	import CutLoad.transitions.ITransition;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	/**
	 * 提示信息管理模块 
	 * @author smallerbird mail:smallerbird@gmail.com  site:www.mkigm.com QQ群:49983196
	 * 
	 */	
	public class CTipManagement extends Base
	{
		private var groupBase:CArray;
		private var tipParent:Sprite;
		//显示辅助边框 
		private var sp_2010_12_25_forTipShowGuide:Sprite=null;
		//把主画现分成几个搜索区域
		private var searchAreaCount:Number;
		//
		private var myTip:CTip;
		private var arrSearch:Array;
		//刷新检测显示提示框的频率
		private var enterFrame_count:Number=0;
		private var enterFrame_i:Number=0;
		private var tipSpace:Number=0;
		//
		private var isStart:Boolean=true;
		//主区域的宽高
		private var mainAreaWidth:Number,mainAreaHeight:Number;
		/**
		 * 初始化
		 * @param refreshOffset 刷新检测显示提示框的频率。1~影片帧频
		 * @param searchAreaCount 把场景会为searchAreaCount行searchAreaCount列个搜索区，注：当鼠标移动时会检测坐标是否在要显示提示框的区域。
		 * @param space 提示框距离鼠标，或边界的间距
		 * <p>重要说明：如果要显示提示框不是以场景为坐标时，请自行添加要添加的坐标，然后可以用setCheckXY设置实时要检查的坐标</p>
		 * 
		 */
		public function init(refreshOffset:Number=15,searchAreaCount:Number=4,space:Number=5):void{
			tipSpace=space;
			this.searchAreaCount=searchAreaCount;
			this.tipParent=this;
			//更新坐标检测用到的区域
			groupBase=new CArray();
			//生成tip
			myTip=new CTip("");
			myTip.setXY(0,0,tipParent);
			myTip.visible=false;
			//
			mainAreaWidth=this.stage.stageWidth;
			this.mainAreaHeight=this.stage.stageHeight;
			//
			//刷新检测显示提示框的频率
			if(refreshOffset>this.stage.frameRate) refreshOffset=this.stage.frameRate;
			if(refreshOffset<=0) refreshOffset=this.stage.frameRate;
			enterFrame_count=Math.floor(this.stage.frameRate/refreshOffset);
			enterFrame_i=enterFrame_count;
			//
			restSearchArea(false);
			this.addEventListener(Event.ENTER_FRAME,enterFrame);
		}
		/**
		 * 设置主区域的宽高,注：默认时不需要设置，自动设置为stage的宽高，只有当设置的提示区域不是主场景时才会.
		 * @param w
		 * @param h
		 * 
		 */		
		public function setMainAreaWH(w:Number,h:Number):void{
			this.mainAreaWidth=w;
			this.mainAreaHeight=h;
		}
		/**
		 * 打开提示，注默认是打开的 
		 * 
		 */		
		public function start():void{
			isStart=true;
		}
		/**
		 * 关闭提示,
		 * 
		 */		
		public function stop():void{
			isStart=false;
		}
		private function enterFrame(e:Event):void{
			if(!isStart) return;
			tipCheckAndShow(this.stage.mouseX,this.stage.mouseY);
		}
		/**
		 * 添加一个提示框 
		 * @param base 要添加提示框的对象
		 * @param tipContent 提示的内容
		 * @param tipWidth 提示框宽度
		 * @param isUpdateRect 是否更新所有的提示框必要的信息。默认true,注：打开会很耗时。当同时要加后多时，可以在前面调用此方法设置false,最后调用这个方法时设置为true.
		 * @param rect 要添加提示框的对象要检测的范围，默认为null,系统会自已生成
		 * 
		 */		
		public function add(base:Sprite,tipContent:String,tipWidth:Number=0,isUpdateRect:Boolean=true,rect:Rectangle=null):void{
			//要显示提示框的对象，提示的内容，要显示区的范围
			if(rect==null) rect=getBaseRectInfo(base)
			var obj:Object={base:base,content:tipContent,w:tipWidth,rect:rect}
			groupBase.add(obj);
			if(isUpdateRect) restSearchArea();
		}
		private function getBaseRectInfo(base:Sprite):Rectangle{
			var postion:Point=base.localToGlobal(new Point(0,0));
			if(base is Base){
				var baseTem:Base=base as Base;
				return new Rectangle(postion.x,postion.y,baseTem.getShowWidth(),baseTem.getShowHeight());
			}else{
				return new Rectangle(postion.x,postion.y,base.width,base.height);
			}
		}
		/**
		 * 刷新，注：重新计算所有坐标，所以很耗时!
		 * 
		 */
		public function update():void{
			if(!isStart) return;
			for(var i:Number=0;i<groupBase.length;i++){
				var objTem:Object=groupBase.getOne(i)
				var base:Base=objTem.base;
				var content:String=objTem.content;
				var obj:Object={base:base,content:content,rect:getBaseRectInfo(base)}
				groupBase.setOne(i,obj);
			}
			restSearchArea();
		}
		/**
		 * 清除所有的提示信息 
		 * 
		 */		
		public function clearAll():void{
			groupBase.clrAll();
			this.stop();
		}
		//更新坐标检测用到的区域
		private function restSearchArea(isUpdateBase:Boolean=true):void{
			//
			arrSearch=new Array();
			var tileW:Number=Math.floor(mainAreaWidth/this.searchAreaCount);
			var tileH:Number=Math.floor(this.mainAreaHeight/this.searchAreaCount);
			//剩余的部份
			var remainingW:Number=mainAreaWidth-(tileW*searchAreaCount);
			var remainingH:Number=mainAreaHeight-(tileH*searchAreaCount);
			//
			var tileWtem:Number,tileHtem:Number,xtem:Number,ytem:Number;
			for(var i:Number=0;i<searchAreaCount;i++){
				var arrRowtem:Array=new Array();
				for(var j:Number=0;j<searchAreaCount;j++){
					//如果是最后一个，要加上剩余的部份
					if(j!=searchAreaCount-1){
						tileWtem=tileW
					}else{
						tileWtem=tileW+remainingW
					}
					if(i!=searchAreaCount-1){
						tileHtem=tileH
					}else{
						tileHtem=tileH+remainingH
					}
					xtem=j*tileW
					ytem=i*tileH
					var rectTem:Rectangle=new Rectangle(xtem,ytem,tileWtem,tileHtem);
					//对加入的元件，分到这些区域
					var arrTem123:Array=new Array();
					//
					var objTem:Object;
					if(isUpdateBase){
						for(var b:Number=0;b<groupBase.length;b++){
							objTem=groupBase.getOne(b)
							var rectTem123:Rectangle=objTem.rect;
							var content123:String=objTem.content;
							if(rectTem.intersects(rectTem123)){
								arrTem123.push({rect:rectTem123,content:content123})
							}
						}
					}
					//
					objTem={rect:rectTem,arr:arrTem123}
					arrRowtem.push(objTem);
				}
				arrSearch.push(arrRowtem);
			}
		}
		/**
		 * 根据传入的坐标，来进行判断是否显示提示框 
		 * @param xx 要检测的x坐标
		 * @param yy 要检测的y坐标
		 * @param offsetX 如果是相对坐标可以在相对坐标基础上加或减去一定的值
		 * @param offsetY 如果是相对坐标可以在相对坐标基础上加或减去一定的值
		 * 
		 */		
		public function tipCheckAndShow(xx:Number,yy:Number,offsetX:Number=0,offsetY:Number=0):void{
			if(enterFrame_i++<enterFrame_count){
				return;
			}
			enterFrame_i=0;
			//
			var ptem:Point=new Point(xx,yy);
			//trace("tip:"+ptem);
			var isSowTip:Boolean=false;
			for(var i:Number=0;i<arrSearch.length;i++){
				for(var j:Number=0;j<arrSearch[i].length;j++){
					var rectTem:Rectangle=arrSearch[i][j].rect;
					if(rectTem.containsPoint(ptem)){
						//
						var arrThisBase:Array=arrSearch[i][j].arr
						for(var k:Number=0;k<arrThisBase.length;k++){
							var obj456:Object=arrThisBase[k]
							rectTem=obj456.rect;
							if(rectTem.containsPoint(ptem)){
								var xxThis:Number=this.stage.mouseX+tipSpace
								var yyThis:Number=this.stage.mouseY+tipSpace
								myTip.setXY(xxThis,yyThis);
								myTip.setText(obj456.content,obj456.w);
								//是否过边界
								xxThis+=myTip.getShowWidth();
								yyThis+=myTip.getShowHeight();
								if(xxThis>this.stage.stageWidth){
									myTip.x-=xxThis-this.stage.stageWidth+tipSpace
								}
								if(yyThis>this.stage.stageHeight){
									myTip.y-=yyThis-this.stage.stageHeight+tipSpace
								}
								isSowTip=true;
							}
						}
						break;
					}
				}
			}
			myTip.visible=isSowTip
		}
		/**
		 * 显示辅助边框 
		 * 
		 */		
		public function showGuide(showParent:Sprite=null):void{
			var tipShowGuideParent:Sprite;
			if(showParent==null){
				tipShowGuideParent=this.tipParent;
			}else{
				tipShowGuideParent=showParent;
			}
			if(sp_2010_12_25_forTipShowGuide!=null) tipShowGuideParent.removeChild(sp_2010_12_25_forTipShowGuide);
			sp_2010_12_25_forTipShowGuide=new Sprite();
			var rectTem:Rectangle;
			//画出显示提示的框
			for(var i:Number=0;i<groupBase.length;i++){
				var objTem:Object=groupBase.getOne(i)
				rectTem=objTem.rect;
				var guideBase:Base=Painter.drawRect(rectTem.width,rectTem.height,RandNO.getRndColor24(),RandNO.getRndInt(1,9)/10,0,0);
				guideBase.setXY(rectTem.x,rectTem.y,sp_2010_12_25_forTipShowGuide);
			}
			//显示检测坐标分的区域 
			for(var k:Number=0;k<arrSearch.length;k++){
				for(var j:Number=0;j<arrSearch[k].length;j++){
					rectTem=arrSearch[k][j].rect;
					var guideBase1:Base=Painter.drawRect(rectTem.width,rectTem.height,0xffffff,0,0,0,null,1);
					guideBase1.setXY(rectTem.x,rectTem.y,sp_2010_12_25_forTipShowGuide);
				}
			}
			tipShowGuideParent.addChild(sp_2010_12_25_forTipShowGuide);
		}
		
		override public function setWH(w:Number=0, h:Number=0):void{
			restSearchArea(true);
		}
		override public function setXY(x:Number, y:Number, myParent:Sprite=null,transitions:ITransition=null):void{
			throw new Error("禁用此方法，它的xy坐标只能0,0");
		}
		override public function show(parent:Sprite):void{
			throw new Error("禁用此方法,因为init,已把自已显示父类");
		}
	}
}